﻿

#region Using Statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Threading;
using System.ComponentModel;
using System.Reflection;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Design;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using Freeform;
using FGame = Freeform.Game;
using XGame = Microsoft.Xna.Framework.Game;
using FComponent = Freeform.Component;

#endregion


namespace Freeform
{
    /// <summary>
    /// Represents an Entity that exists in a 2D world.
    /// </summary>
    public class TileLevelDrawEntity : Entity2D
    {

        #region Members
        /// <summary>
        /// A colour used to overlay the drawn textures.
        /// </summary>
        public Color ColourOverlay { get; set; }

        /// <summary>
        /// Gets or sets the depth of the actor. (0 - front of viewport, 1 - back of viewport.)
        /// </summary>
        public Single Depth { get; set; }

        /// <summary>
        /// Gets or sets the stored Tile Level.
        /// </summary>
        public TileMap2D TileMap { get; set; }

        ///<summary>
        /// A list of rectangles used for selection the correct portion of the TileSet's source image.
        /// </summary>
        public List<Rectangle> TileSetSources { get; set; }

        #endregion


        #region Init

        /// <summary>
        /// Creates a new entity and automatically links it to the given world.
        /// </summary>
        /// <param name="World">The world that this entity belongs to.</param>
        public TileLevelDrawEntity(World World, TileMap2D Map)
            : base(World)
        {
            ColourOverlay = Color.White;
            Position = new Vector2(1, 1);
            TileMap = Map;
            TileSetSources = new List<Rectangle>();
            int numTilesHigh = TileMap.TileSet.Height / TileMap.TileHeight;
            int numTilesWide = TileMap.TileSet.Width / TileMap.TileWidth;
            int numberOfTiles = numTilesHigh * numTilesWide;

            int Rows = 0;
            int Incrementer = 0;
            for(int i = 0; i < numberOfTiles; i ++)
            {
                TileSetSources.Add(new Rectangle(TileMap.TileWidth * Incrementer, TileMap.TileHeight * Rows, TileMap.TileWidth, TileMap.TileHeight));
                Incrementer++;
                if (i != 0 && i % numTilesWide == 0)
                {
                    Rows++;
                    Incrementer = 0;
                }
            }
        }

        #endregion


        #region Update


        #endregion


        #region Draw

        /// <summary>
        /// Allows the entity to draw itself.
        /// </summary>
        /// <param name="Time">Provides a snapshot of timing values.</param>
        /// <param name="Viewport">The viewport to render to.</param>
        public override void Draw(GameTime Time, Viewport Viewport)
        {
            base.Draw(Time, Viewport);

            Viewport2D View = Viewport as Viewport2D;
            if (View == null) return;

            // Check early breaks.
            if (Viewport.SpriteBatch == null) return;

            // Calculate drawing data.
            Vector2 Draw_Position = View.Camera.TransformPosition(Position);
            Vector2 Draw_Size = View.Camera.TransformSize(Size);
            Vector2 Draw_Origin = new Vector2(TileMap.Layers[0].Width / 2, TileMap.Layers[0].Height / 2);

            // Draw entity.
            for (int i = 0; i < TileMap.Layers.GetLength(0); i++)
            {
                int Accumulator = 0;
                for(int y = TileMap.Layers[i].Height - 1; y >= 0 ; y--)
                    for (int x = 0; x < TileMap.Layers[i].Width; x++)
                    {
                        if (TileMap.Layers[i].MapGrid[y, x] <= 0) continue;
                        
                        Rectangle Draw_Destination = new Rectangle((int)Draw_Position.X + ((x * TileMap.TileWidth / 2) + (y * TileMap.TileWidth / 2)), 
                            (int)Draw_Position.Y + ((y * TileMap.TileHeight / 2) - (x * TileMap.TileHeight / 2)),
                            (int)Draw_Size.X * TileMap.TileWidth, 
                            (int)Draw_Size.Y * TileMap.TileHeight);
                        
                        Accumulator++;

                        Rectangle Draw_Source = TileSetSources[TileMap.Layers[i].MapGrid[y, x] - 1];
                        Viewport.SpriteBatch.Draw(TileMap.TileSet, Draw_Destination, Draw_Source, ColourOverlay, Orientation, Draw_Origin, SpriteEffects.None, Depth);
                        //Viewport.SpriteBatch.DrawString(View.DebugFont, Accumulator.ToString(), new Vector2(Draw_Destination.X, Draw_Destination.Y), Color.Yellow); 
                    }
            }
        }

        #endregion


        #region Dispose


        #endregion


        #region Utility


        #endregion





            //        for (int i = 0; i < TileMap.Layers.GetLength(0); i++)
            //{
            //    for(int y = 0; y < TileMap.Layers[i].Height; y++)
            //        for (int x = 0; x < TileMap.Layers[i].Width; x++)
            //        {
            //            if (TileMap.Layers[i].MapGrid[y, x] <= 0) continue;
            //            //Standard top down dt
            //            Rectangle Draw_Destination = new Rectangle((int)Draw_Position.X + (x* TileMap.TileWidth), (int)Draw_Position.Y + (y * TileMap.TileHeight), (int)Draw_Size.X * TileMap.TileWidth, (int)Draw_Size.Y * TileMap.TileHeight);
            //            Rectangle Draw_Source = TileSetSources[TileMap.Layers[i].MapGrid[y, x] - 1];
            //            Viewport.SpriteBatch.Draw(TileMap.TileSet, Draw_Destination, Draw_Source, ColourOverlay, Orientation, Draw_Origin, SpriteEffects.None, Depth);
            //        }
            //}
    }
}